using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;
using bookmeetingroom.Data.Entities;
using bookmeetingroom.ViewModel;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.IdentityModel.Tokens;

namespace bookmeetingroom.Controllers
{

    [Route("api/[controller]")]
    [ApiController]
    [Produces("application/json")]
    public class TokenController : ControllerBase
    {
        private readonly SignInManager<ApplicationUser> _signInManager;
        private readonly UserManager<ApplicationUser> _userManager;
        private readonly IConfiguration _configuration;
        public TokenController(SignInManager<ApplicationUser> signInManager,
            UserManager<ApplicationUser> userManager, IConfiguration configuration)
        {
            _signInManager = signInManager;
            _userManager = userManager;
            _configuration = configuration;
        }
        [HttpGet]
        public IActionResult Get()
        {

            return Ok("test");
        }
        [HttpPost]
        public async Task<IActionResult> UserToken(LoginViewModel model)
        {
            string errorMessage = "无效的用户名或密码";

            if (!ModelState.IsValid)
            {
                return BadRequest(errorMessage);
            }
            var user = await _userManager.FindByEmailAsync(model.Email);

            if (user == null)
            {
                return BadRequest("用户不存在");
            }
            if (await _userManager.IsLockedOutAsync(user)) return BadRequest("当前用户已经被锁定");

            var result = await _signInManager.PasswordSignInAsync(user, model.Password, true, true);

            if (!result.Succeeded) return BadRequest(errorMessage);

            var token = await GenerateToken(user);

            return Ok(token);
        }
        private async Task<TokenViewModel> GenerateToken(ApplicationUser user)
        {
            var claims = new List<Claim> {
                new Claim (JwtRegisteredClaimNames.Sub, user.UserName),
                new Claim (JwtRegisteredClaimNames.Jti, Guid.NewGuid ().ToString ()),
                new Claim (ClaimTypes.NameIdentifier, user.Id.ToString ()),
                new Claim (ClaimTypes.Name, user.UserName),
                new Claim(ClaimTypes.GroupSid,user.CompanyId.ToString())
            };
            var roles = await _userManager.GetRolesAsync(user);

            foreach (var role in roles)
            {
                claims.Add(new Claim(ClaimTypes.Role, role));
            }
            var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["Authentication:JwtKey"]));
            var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
            var expires = DateTime.Now.AddDays(Convert.ToDouble(_configuration["Authentication:JwtExpireDays"]));

            var token = new JwtSecurityToken(_configuration["Authentication:JwtIssuer"], _configuration["Authentication:JwtAudience"], claims, expires: expires, signingCredentials: creds);
            return new TokenViewModel
            {
                AccessToken = new JwtSecurityTokenHandler().WriteToken(token),
                AccessTokenExpiration = expires,
                UserName = user.UserName,
                Avatar=user.Avatar,
                FullName=user.FullName,
                Roles = roles
            };
        }

    }
}